package com.finalist.util;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * 字符处理工具类
 * @author pengyb
 *
 */
public class StringUtils
{

    /**
     * 格式化mac地址：去掉冒号，全部大写
     * @param mac
     * @return
     */
    public static String formatMac(String mac)
    {
        return mac.replaceAll(":", "").toUpperCase();
    }

    /**
     * 首字母大写化
     * @param src   字符串
     * @return      首字母大写后的字符串
     */
    public static String upperFirstLetter(String src)
    {
        return src.substring(0, 1).toUpperCase() + src.substring(1);
    }

    /**
     * 首字母小写
     * @param src   字符串
     * @return      首字母小写后的字符串
     */
    public static String lowerFirstLetter(String src)
    {
        return src.substring(0, 1).toLowerCase() + src.substring(1);
    }

    /**
     * 将字符串分割成字符串List
     * @param source 源字符串
     * @param splitTag 分割字符
     * @return List<String> 字符串List
     * @author zsl
     */
    public static List<String> split2List(String source, String splitTag)
    {
        List<String> StrList = new ArrayList<String>();
        List<String> specTaglist = new ArrayList<String>();
        String[] specTag = { "|", "+", "*", "/", ".", "^" };
        for (int j = 0; j < specTag.length; j++)
        {
            specTaglist.add(specTag[j]);
        }
        if (specTaglist.contains(splitTag))
        {
            splitTag = "\\" + splitTag;
        }
        String[] strArray = source.split(splitTag);
        for (int i = 0; i < strArray.length; i++)
        {
            StrList.add(strArray[i]);
        }
        return StrList;
    }

    /**
     * 取出数组或List中最大或者最小值(支持日期型、整型、字符串、字符型的基本排序)
     * @param sortMode 0-由小到大 1-由大到小
     * @param arrayData 数组数据 不存在值传null
     * @param listData list数据 不存在值传null
     * @return 最大值or最小值
     * @author zsl
     */
    @SuppressWarnings("unchecked")
    public static <T> T sortData(String sortMode, T[] arrayData, List<T> listData)
    {
        T obj = null;
        T[] arrayData1 = null;
        if ("0".equals(sortMode))
        {
            if (arrayData != null)
            {
                Arrays.sort(arrayData);
                obj = arrayData[0];
            }
            else
            {
                arrayData1 = (T[]) listData.toArray();
                Arrays.sort(arrayData1);
                obj = arrayData1[0];
            }

        }
        else
        {
            if (arrayData != null)
            {
                Arrays.sort(arrayData, Collections.reverseOrder());
                obj = arrayData[0];
            }
            else
            {
                arrayData1 = (T[]) listData.toArray();
                Arrays.sort(arrayData1, Collections.reverseOrder());
                obj = arrayData1[0];
            }
        }
        return obj;
    }

    /**
     * 字符串是否含有全角字符
     * @param src   字符串
     * @return      true-有，false-没有
     */
    public static boolean hasSBC(String src)
    {
        char[] c = src.toCharArray();
        for (int i = 0; i < c.length; i++)
        {
            if (c[i] < 32 || c[i] > 126)
            {
                return true;
            }
        }
        return false;
    }

    /**
     * 字符串是否含有半角字符
     * @param src   角字符
     * @return      true-有，false-没有
     */
    public static boolean hasDBC(String src)
    {
        char[] c = src.toCharArray();
        for (int i = 0; i < c.length; i++)
        {
            if (c[i] >= 32 && c[i] <= 126)
            {
                return true;
            }
        }
        return false;
    }

    /**
     * 字符串是否包含中文
     * @param src   字符串
     * @return      true-包含，false-不包含
     */
    public static boolean hasChinese(String src)
    {
        char[] c = src.toCharArray();
        for (int i = 0; i < c.length; i++)
        {
            if (c[i] >= 0x4E00 && c[i] <= 0x9FA5)
            {
                return true;
            }
        }
        return false;
    }

    /**
     * 字符串是否包含阿拉伯数字
     * 包括全角和半角
     * @param src   字符串
     * @return      true-包含，false-不包含
     */
    public static boolean hasNumber(String src)
    {
        char[] c = src.toCharArray();
        for (int i = 0; i < c.length; i++)
        {
            if (c[i] >= 0x0030 && c[i] <= 0x0039)
            {//半角
                return true;
            }
            else if (c[i] >= 0xFF10 && c[i] <= 0xFF19)
            {//全角
                return true;
            }
        }
        return false;
    }

    /**
     * 字符串是否包含英文字母
     * 包括全角和半角
     * 包括大小写
     * @param src   字符串
     * @return      true-包含，false-不包含
     */
    public static boolean hasLetter(String src)
    {
        char[] c = src.toCharArray();
        for (int i = 0; i < c.length; i++)
        {
            if (c[i] >= 0x0041 && c[i] <= 0x005A)
            {//半角大写
                return true;
            }
            else if (c[i] >= 0x0061 && c[i] <= 0x007A)
            {//半角小写
                return true;
            }
            else if (c[i] >= 0xFF21 && c[i] <= 0xFF3A)
            {//全角大写
                return true;
            }
            else if (c[i] >= 0xFF41 && c[i] <= 0xFF5A)
            {//全角小写
                return true;
            }
        }
        return false;
    }

    /**
     * 半角转全角
     * 半角空格为32，全角空格为12288
     * 其他字符半角(33-126)与全角(65281-65374)的对应关系为：相差65248
     * @param src   待转换的字符串
     * @return      转换后的全角字符串
     */
    public static String toSBC(String src)
    {
        char[] c = src.toCharArray();
        for (int i = 0; i < c.length; i++)
        {
            if (c[i] == 32)
            {
                c[i] = 12288;
            }
            else if (c[i] >= 33 && c[i] <= 126)
            {
                c[i] += 65248;
            }
        }
        return new String(c);
    }

    /**
     * 全角转半角
     * 半角空格为32，全角空格为12288
     * 其他字符半角(33-126)与全角(65281-65374)的对应关系为：相差65248
     * @param src   待转换的字符串
     * @return      转换后的半角字符串
     */
    public static String toDBC(String src)
    {
        char[] c = src.toCharArray();
        for (int i = 0; i < c.length; i++)
        {
            if (c[i] == 12288)
            {
                c[i] = 32;
            }
            else if (c[i] >= 65281 && c[i] <= 65374)
            {
                c[i] -= 65248;
            }
        }
        return new String(c);
    }

    /**
     * 不带覆盖的查找某字符串在另一字符串中出现的次数
     * 如：字符串“OKO“在字符串“OKOKOKO”中出现2次，而不是3次
     * @param orgStr 源字符串
     * @param subStr 查找字符串
     * @return
     */
    public static int countSubStrWithOutCover(String orgStr, String subStr)
    {
        int total = 0;
        for (String tmp = orgStr; tmp != null && tmp.length() >= subStr.length();)
        {
            if (tmp.indexOf(subStr) == 0)
            {
                total++;
                tmp = tmp.substring(subStr.length());
            }
            else
            {
                tmp = tmp.substring(1);
            }
        }
        return total;
    }

    /**
     * 带覆盖的查找某字符串在另一字符串中出现的次数
     * 如：字符串“OKO“在字符串“OKOKOKO”中出现3次，而不是2次
     * @param orgStr 源字符串
     * @param subStr 查找字符串
     * @return
     */
    public static int countSubStrWithCover(String orgStr, String subStr)
    {
        int total = 0;
        for (String tmp = orgStr; tmp != null && tmp.length() >= subStr.length();)
        {
            if (tmp.indexOf(subStr) == 0)
            {
                total++;
            }
            tmp = tmp.substring(1);
        }
        return total;
    }

    /**
     * 统计某字符串在另一大字符串中出现的次数
     * 情况如下：
     * StringUtils.countMatches(null, *)       = 0
     * StringUtils.countMatches("", *)         = 0
     * StringUtils.countMatches("abba", null)  = 0
     * StringUtils.countMatches("abba", "")    = 0
     * StringUtils.countMatches("abba", "a")   = 2
     * StringUtils.countMatches("abba", "ab")  = 1
     * StringUtils.countMatches("abba", "xxx") = 0
     * </pre>
     *
     * @param str  the String to check, may be null
     * @param sub  the substring to count, may be null
     * @return the number of occurrences, 0 if either String is <code>null</code>
     */
    public static int countMatches(String str, String sub)
    {
        if (isEmpty(str) || isEmpty(sub))
        {
            return 0;
        }
        int count = 0;
        int idx = 0;
        while ((idx = str.indexOf(sub, idx)) != -1)
        {
            count++;
            idx += sub.length();
        }
        return count;
    }

    /**
     * 校验某字符串是否是只包含数字
     * A decimal point is not a unicode digit and returns false.</p>
     * 校验情况如下：
     * StringUtils.isNumeric(null)   = false
     * StringUtils.isNumeric("")     = true
     * StringUtils.isNumeric("  ")   = false
     * StringUtils.isNumeric("123")  = true
     * StringUtils.isNumeric("12 3") = false
     * StringUtils.isNumeric("ab2c") = false
     * StringUtils.isNumeric("12-3") = false
     * StringUtils.isNumeric("12.3") = false
     * </pre>
     *
     * @param str  the String to check, may be null
     * @return <code>true</code> if only contains digits, and is non-null
     */
    public static boolean isNumeric(String str)
    {
        if (str == null)
        {
            return false;
        }
        int sz = str.length();
        for (int i = 0; i < sz; i++)
        {
            if (Character.isDigit(str.charAt(i)) == false)
            {
                return false;
            }
        }
        return true;
    }

    /**
     * 判断字符串是否不为空（不为null且不是""）
     * @param src 字符串
     * @return true-字符串不为空 false-字符串为空
     */
    public static boolean isNotEmpty(String src)
    {
        if (src != null && !"".equals(src.trim()))
        {
            return true;
        }
        return false;
    }

    /**
     * 判断字符串是否为空（为null或者""）
     * @param src 字符串
     * @return true-字符串为空 false-字符串不为空
     */
    public static boolean isEmpty(String src)
    {
        if (src != null && !"".equals(src.trim()))
        {
            return false;
        }
        return true;
    }

    /**
     * 字符串翻转
     * 如：“123” 翻转后变成  “321”
     * @param src 翻转的字符串
     * @return
     */
    public static String reverse(String src)
    {
        if (src == null)
        {
            return null;
        }
        //将String 对象转换为可改变的StringBuffer类对象 
        //然后调用StringBuffer类的reverse()方法实现反转 
        return new StringBuffer(src).reverse().toString();
    }
}
